home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: delta / whiteline CD Series - delta.iso / games / litt_200 / source / little15.c < prev   
C/C++ Source or Header  |  1995-11-25  |  24KB  |  965 lines

  1. /*    ######################################################################
  2.     # little15.c - Ein kleines simples GEM-Spiel für Zwischendurch
  3.     # @(#) Programm:  LITTLE15.APP
  4.     # @(#) Start:     02.11.1994
  5.     # @(#) Version:   08.09.1995
  6.     # @(#) Copyright: Dirk Hagedorn, In der Esmecke 9, D-59846 Sundern
  7.     # @(#) Kostenlose Weitergabe erlaubt!
  8.     ######################################################################
  9.     # 08.09.1995: Anpassungen an SysGem2, Veröffentlichung des Quelltextes
  10.     ######################################################################    */
  11.  
  12. #ifndef        RSC_INCLUDE
  13. #define        RSC_INCLUDE    1                /* 1: Resource einbinden */
  14. #endif
  15.  
  16.  
  17. #ifdef __ENGLISH__
  18. #define    RSC_NAME    "litt_eng.rsc"
  19. #define    RSC_H        "litt_eng.h"
  20. #define    RSC_RH        "litt_eng.rh"
  21. #define    RSC_RSH        "litt_eng.rsh"
  22. #else
  23. #define    RSC_NAME    "litt_ger.rsc"
  24. #define    RSC_H        "litt_ger.h"
  25. #define    RSC_RH        "litt_ger.rh"
  26. #define    RSC_RSH        "litt_ger.rsh"
  27. #endif
  28.  
  29.     
  30. /*    ######################################################################
  31.     # Includes
  32.     ######################################################################    */
  33.  
  34. #include    <stdio.h>
  35. #include    <stdlib.h>
  36. #include    <string.h>
  37. #include    <aes.h>
  38. #include    <vdi.h>
  39. #include    <time.h>
  40. #include    <sys_gem2.h>
  41.  
  42. #include    RSC_H
  43.  
  44. #if RSC_INCLUDE
  45. #include    RSC_RH
  46. #include    RSC_RSH
  47. #endif
  48.  
  49.  
  50. /*    ######################################################################
  51.     # Resource
  52.     ######################################################################    */
  53.  
  54. #if RSC_INCLUDE
  55. #define    t_deskmenu        rs_trindex[T_DESKMENU]
  56. #define    t_menu            rs_trindex[T_MENU]
  57. #define    t_info            rs_trindex[T_INFO]
  58. #define    t_auth            rs_trindex[T_AUTH]
  59. #define    t_fair            rs_trindex[T_FAIR]
  60. #define    t_imag            rs_trindex[T_IMAG]
  61. #define    a_new_game        rs_frstr[A_NEW_GAME]
  62. #define    a_no_window        rs_frstr[A_NO_WINDOW]
  63. #define    a_no_dragdrop    rs_frstr[A_NO_DRAGDROP]
  64. #define    a_quit            rs_frstr[A_QUIT]
  65. #else
  66. OBJECT    *t_deskmenu,
  67.         *t_menu,
  68.         *t_info,
  69.         *t_auth,
  70.         *t_fair,
  71.         *t_imag;
  72. char    *a_new_game,
  73.         *a_no_window,
  74.         *a_no_dragdrop,
  75.         *a_quit;
  76. #endif
  77.  
  78.  
  79.  
  80. /*    ######################################################################
  81.     # Makros
  82.     ######################################################################    */
  83. #define    accessory        (par.acc_entry>-1)
  84.  
  85.  
  86. /*    ######################################################################
  87.     # Konstanten
  88.     ######################################################################    */
  89. /* Applikations-Strings wie Fenstertitel, Accessory-Name etc. */
  90.  
  91. char    *SUBTITLE=        "LITTLE15",                /* Iconify-Titel */
  92.         *WINTITLE=        "Little 15",            /* Fenstertitel  */
  93.         *APP_NAME=        "Little 15",            /* Programm-Name */
  94.         *APP_VERSION=    "2.0",                    /* Version       */
  95.         *ACC_NAME=        "  Little 15 ",            /* ACC-Eintrag   */
  96.         *APP_WIDMUNG=    "FÜR ANDREA & MAREEN",    /* Widmung       */
  97.         *HYPFILE=        "*:\\little15.hyp";        /* Hypertext     */
  98.  
  99. /* Anzahl an Grafiksätzen in der RSC */
  100. #define    IMAGESETS    2
  101.  
  102. /* Spielfeld-Breite und -Höhe */
  103. #define    WIDTH    4    
  104. #define    HEIGHT    4
  105.  
  106. /* Zwischenraum zwischen Images und Fensterrand */
  107. #define    BORDER    16
  108.  
  109.  
  110. /* Der Wert des freien Feldes */
  111. #define    ISFREE    HEIGHT*WIDTH
  112.  
  113. /* Makro zum Testen, ob ein Stein an der richtigen Stelle ist, */
  114. /* also ob der Wert des Feldes mit dem Sollwert übereinstimmt  */
  115. #define fieldsolved(y,x)    ((y*WIDTH)+x+1)    
  116.  
  117. /* Applikations-ID und Fenster-IDs*/
  118. #define    APP_ID                'LI15'    
  119. #define    MAINID                'MAIN'
  120. #define    INFOID                'INFO'
  121. #define    AUTHID                'AUTH'
  122. #define    FAIRID                'FAIR'
  123.  
  124. /* Sooft werden die Felder bei den verschiedenen */
  125. /* Schwierigkeitsstufen durcheinandergewürfelt */
  126. #define TIMES_VERY_EASY        10
  127. #define TIMES_EASY            20
  128. #define TIMES_MEDIUM        50
  129. #define TIMES_DIFF            100
  130. #define TIMES_VERY_DIFF        200
  131.  
  132.  
  133. /* Hilfsmatrix mit Objektnamen aus little15.h */
  134. static const int GAMEIMAGE[IMAGESETS][HEIGHT*WIDTH]=
  135. {
  136.     {    NUMB_01, NUMB_02, NUMB_03, NUMB_04,
  137.         NUMB_05, NUMB_06, NUMB_07, NUMB_08,
  138.         NUMB_09, NUMB_10, NUMB_11, NUMB_12,
  139.         NUMB_13, NUMB_14, NUMB_15, NUMB_00
  140.     },
  141.     {    LETT_A, LETT_B, LETT_C, LETT_D, 
  142.         LETT_E, LETT_F, LETT_G, LETT_H,
  143.         LETT_I, LETT_J, LETT_K, LETT_L,
  144.         LETT_M, LETT_N, LETT_O, LETT_0
  145.     }
  146. };
  147.  
  148.  
  149.  
  150. /*    ######################################################################
  151.     # Typen
  152.     ######################################################################    */
  153. typedef enum
  154. {    L_VERY_EASY, L_EASY, L_MEDIUM, L_DIFFICULT, L_VERY_DIFFICULT
  155. }    LEVEL;
  156.  
  157. typedef enum
  158. {    IS_NUMBERS, IS_LETTERS
  159. }    IMGSET;
  160.  
  161.  
  162.  
  163. /*    ######################################################################
  164.     # Variablen
  165.     ######################################################################    */
  166. PARAMETER    par;
  167. BITBLK        *i_iconify, *dh_iconify;
  168.  
  169.  
  170. static IMGSET        imgset;
  171. static LEVEL        level;
  172.  
  173. /* Die Koordinaten des freien Feldes */
  174. static int free_y, free_x;
  175.  
  176. /* Das Spielfeld als Matrix */
  177. static int field[HEIGHT+1][WIDTH+1];
  178.  
  179. /* Breite und Höhe der G_IMAGEs */
  180. static int imgheight, imgwidth;
  181.  
  182. /* Koordinaten der Fenster */
  183. static int x_main, y_main;
  184. static int x_info, y_info;
  185.  
  186. /* Der Zeichenbereich des Spielfensters */
  187. static RECT work;
  188.  
  189.  
  190. /* MFDBs und Array für das VDI */
  191. MFDB mfdb_field, mfdb_screen;
  192. int pxy[8], color[2];
  193.  
  194.  
  195. /*    ######################################################################
  196.     #  Alertboxen
  197.     ######################################################################    */
  198. /*    ----------------------------------------------------------------------
  199.     <- TRUE: Programm beenden
  200.     ----------------------------------------------------------------------    */
  201. static BOOLEAN alert_quit ( void )
  202. {
  203.     return ( 1==Alert(ALERT_NORM, 1, a_quit) );
  204. }    /* alert_quit */
  205.  
  206.  
  207. /*    ----------------------------------------------------------------------
  208.     <- TRUE: Neues Spiel
  209.     ----------------------------------------------------------------------    */
  210. static BOOLEAN alert_new_game ( void )
  211. {
  212.     return ( 1==Alert(ALERT_NORM, 1, a_new_game) );
  213. }    /* alert_new_game */
  214.  
  215.  
  216. /*    ----------------------------------------------------------------------
  217.     Warnung, daß kein Fenster mehr zur Verfügung steht
  218.     ----------------------------------------------------------------------    */
  219. static void alert_no_window ( void )
  220. {
  221.     Alert(ALERT_NORM, 1, a_no_window);
  222. }
  223.  
  224. /*    ----------------------------------------------------------------------
  225.     Warnung, daß Drag & Drop nicht unterstützt wird
  226.     ----------------------------------------------------------------------    */
  227. static void alert_no_dragdrop ( void )
  228. {
  229.     Alert(ALERT_NORM, 1, a_no_dragdrop);
  230. }
  231.  
  232.  
  233. /*    ----------------------------------------------------------------------
  234.     Warnung, daß RSC nicht geladen werden konnte
  235.     ----------------------------------------------------------------------    */
  236. #if (!RSC_INCLUDE)
  237. static void alert_rsc_error ( void )
  238. {
  239.     Alert(ALERT_NORM, 1, "[3][RSC-Datei nicht gefunden!|RSC-file not found!][ [OK ]");
  240. }    /*alert_rsc_error*/
  241. #endif
  242.  
  243.  
  244.  
  245. /*    ######################################################################
  246.     # 
  247.     # Info-Dialoge
  248.     #
  249.     ######################################################################    */
  250.  
  251. /*    ######################################################################
  252.     # Autor-Dialog
  253.     ######################################################################    */
  254. static void open_author ( void )
  255. {
  256.     char wintitle[256];
  257.  
  258.     GetText(t_auth, AUTH_TITLE, wintitle);
  259.     SetFlags(t_auth, AUTH_TITLE, HIDETREE);    
  260.  
  261.     SetText(t_auth, AUTH_WIDMUNG, APP_WIDMUNG);
  262.     DoDialog(t_auth, 0, wintitle);
  263.     
  264. }    /*open_author*/
  265.  
  266.  
  267.  
  268.  
  269. /*    ######################################################################
  270.     # Fairware-Dialog
  271.     ######################################################################    */
  272. void open_fair ( void )
  273. {
  274.     char wintitle[256];
  275.  
  276.     GetText(t_fair, FAIR_TITLE, wintitle);
  277.     SetFlags(t_fair, FAIR_TITLE, HIDETREE);    
  278.  
  279.     DoDialog(t_fair, 0, wintitle);
  280.  
  281. }    /*open_fair*/
  282.  
  283.  
  284. int handle_info (int msg, int button, DIALOG_INFO *inf)
  285. {
  286.     char s[32];
  287.     
  288.     switch (msg)
  289.     {
  290.         case SG_KEY:
  291.             return(SG_KEYCONT);
  292.  
  293.         case SG_NOWIN:
  294.             break;
  295.  
  296.         case SG_START:
  297.             LinkImage(inf->id, dh_iconify, "INFO");
  298.             sprintf(s, "VERSION %s (%s)", APP_VERSION, __DATE__);
  299.             SetText(t_info, INFO_VERSION, s);
  300.             break;
  301.  
  302.         case SG_POSX:    x_info= button;    break;
  303.         case SG_POSY:    y_info= button;    break;
  304.         
  305.         case SG_QUIT:
  306.             return (SG_CONT);
  307.             
  308.         case SG_END:
  309.             switch (button)
  310.             {
  311.                 case -1:
  312.                 case INFO_OK:
  313.                     return (SG_CLOSE);
  314.                 case INFO_LEGAL:
  315.                     open_fair();
  316.                     break;
  317.                 case INFO_AUTHOR:
  318.                     open_author();
  319.                     break;
  320.             }
  321.             break;
  322.         case SG_DRAGDROP:
  323.             alert_no_dragdrop();
  324.             break;
  325.     }
  326.     
  327.     return (SG_CONT);
  328.  
  329. } /*handle_info*/
  330.  
  331.  
  332. void open_info ( void )
  333. {
  334.     char wintitle[256];
  335.  
  336.     GetText(t_info, INFO_TITLE, wintitle);
  337.     SetFlags(t_info, INFO_TITLE, HIDETREE);    
  338.  
  339.     WindowDialog(
  340.         INFOID,                /* ID         */
  341.         x_info, y_info,        /* Position   */
  342.         wintitle,            /* Titel      */
  343.         "",                    /* Info       */
  344.         TRUE,                /* Closer?    */
  345.         FALSE,                /* modal?     */
  346.         t_info,                /* Objektbaum */
  347.         NULL,                /* Menüzeile  */
  348.         0,                    /* Editfeld   */
  349.         NULL,                /* Userzeiger */
  350.         handle_info            /* Handler    */
  351.     );
  352.  
  353. } /*open_info*/
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361. /*    ######################################################################
  362.     # 
  363.     # Das Spiel an sich
  364.     #
  365.     ######################################################################    */
  366. /*    ----------------------------------------------------------------------
  367.     Ein Feld mittels VDI-Funktionen zeichnen und ggf. die Maus ausschalten
  368.     Kopieren des BITBLK eines G_IMAGE auf den Screen
  369.     ----------------------------------------------------------------------    */
  370. void draw_field (int y, int x, BOOLEAN mouseoff)
  371. {
  372.     int    obimg;
  373.     
  374.     if ( (x<0) || (y<0) || (x>WIDTH) || (y>HEIGHT) )
  375.     {    return;
  376.     }
  377.  
  378.     obimg= GAMEIMAGE[imgset][field[y][x]-1];
  379.  
  380.     mfdb_field.fd_addr= (void *) t_imag[obimg].ob_spec.bitblk->bi_pdata;
  381.     
  382.     pxy[4]= work.x + BORDER + x*imgwidth;
  383.     pxy[5]= work.y + BORDER + y*imgheight;
  384.     pxy[6]= pxy[4]+imgwidth-1;
  385.     pxy[7]= pxy[5]+imgheight-1;
  386.  
  387.     if (mouseoff)    HideMouse();
  388.  
  389.     vrt_cpyfm(par.vdi_handle, MD_REPLACE, pxy, &mfdb_field, &mfdb_screen, color);
  390.  
  391.     if (mouseoff)    ShowMouse();
  392. }    /* draw_field */
  393.  
  394.  
  395.  
  396. /*    ----------------------------------------------------------------------
  397.     Komplettes Spielfenster neu zeichnen.
  398.     ----------------------------------------------------------------------    */
  399. void redraw_game (WINDOW_INFO *inf)
  400. {
  401.     int x, y;
  402.  
  403.     work.x= inf->draw_area.x;
  404.     work.y= inf->draw_area.y;
  405.     
  406.     HideMouse();
  407.     for (y=0; y<HEIGHT; y++)
  408.     {    for (x=0; x<WIDTH; x++)
  409.         {    draw_field(y, x, FALSE);
  410.         }    
  411.     }
  412.     ShowMouse();
  413.  
  414. }    /* redraw_game */
  415.  
  416.  
  417.  
  418. /*    ----------------------------------------------------------------------
  419.     <- TRUE: Spiel gelöst
  420.     ----------------------------------------------------------------------    */
  421. static BOOLEAN game_solved ( void )
  422. {
  423.     int y, x;
  424.     
  425.     for (y=0; y<HEIGHT; y++)
  426.     {    for (x=0; x<WIDTH; x++)
  427.         {    if (field[y][x]!=fieldsolved(y,x))
  428.             {    return(FALSE);
  429.             }
  430.         }
  431.     }
  432.  
  433.     return (TRUE);
  434.         
  435. }    /*game_solved*/
  436.  
  437.  
  438.  
  439. /*    ----------------------------------------------------------------------
  440.     <- TRUE: Ein Feld wurde umbewegt
  441.     ----------------------------------------------------------------------    */
  442. static BOOLEAN move_field ( int y, int x, BOOLEAN draw )
  443. {
  444.     int hilf;
  445.  
  446.     /* Stimmen die Koordinaten? */    
  447.     if ( (y<0) || (x<0) || (y>=HEIGHT) || (x>=WIDTH) )
  448.     {    return(FALSE);
  449.     }
  450.  
  451.     /* Liegt angeklicktes Feld neben dem freien Feld? */
  452.     if    (    ( (free_y==y) && ( (free_x==(x-1)) || (free_x==(x+1)) ) )
  453.         ||    ( (free_x==x) && ( (free_y==(y-1)) || (free_y==(y+1)) ) )
  454.         )
  455.     {
  456.         /* Feldinhalte tauschen */
  457.         hilf= field[free_y][free_x];
  458.         field[free_y][free_x]= field[y][x];
  459.         field[y][x]= hilf;
  460.         
  461.         if (draw)
  462.         {    draw_field(free_y, free_x, TRUE);
  463.             draw_field(y, x, TRUE);
  464.         }
  465.     
  466.         free_y= y;
  467.         free_x= x;
  468.         
  469.         return(TRUE);
  470.     }
  471.     
  472.     return (FALSE);
  473. }    /*move_field*/
  474.  
  475.  
  476.  
  477.  
  478. /*    ----------------------------------------------------------------------
  479.     init_game() initialisiert das Spiel und zeichnet es ggf.
  480.     ----------------------------------------------------------------------    */
  481. static void init_game ( BOOLEAN draw )
  482. {
  483.     int y, x, sooft, i, ry, rx;
  484.     
  485.     for (y=0; y<HEIGHT; y++)
  486.     {    for (x=0; x<WIDTH; x++)
  487.         {    field[y][x]= fieldsolved(y,x);
  488.         }
  489.     }
  490.     
  491.     free_y= HEIGHT-1;    /* Freies Feld liegt rechts unten */
  492.     free_x= WIDTH-1;
  493.     
  494.     switch(level)
  495.     {    case L_VERY_EASY:        sooft= TIMES_VERY_EASY;    break;
  496.         case L_EASY:            sooft= TIMES_EASY;        break;
  497.         case L_MEDIUM:            sooft= TIMES_MEDIUM;    break;
  498.         case L_DIFFICULT:        sooft= TIMES_DIFF;        break;
  499.         case L_VERY_DIFFICULT:    sooft= TIMES_VERY_DIFF;    break;
  500.     }
  501.  
  502.  
  503.     /* Spielfeld durcheinanderwürfeln je nach Level      */
  504.     /* Dazu einfach ein paar Mal die Nachbarn des freien */
  505.     /* Feldes umbewegen. Spiel ist immer lösbar!         */
  506.  
  507.     for (i=0; i<sooft; i++)
  508.     {    switch ( (rand() % 4) )
  509.         {    case 0:        ry= free_y-1;    rx=free_x;    break;
  510.             case 1:        ry= free_y+1;    rx=free_x;    break;
  511.             case 2:        ry= free_y;        rx=free_x-1;    break;
  512.             default:    ry= free_y;        rx=free_x+1;    break;
  513.         }
  514.         move_field(ry, rx, FALSE);
  515.     }
  516.  
  517.     if (draw)
  518.     {    RedrawWindow(GetHandle(MAINID));
  519.     }
  520.     
  521. }    /*init_game*/
  522.  
  523.  
  524.  
  525.  
  526. /*    ----------------------------------------------------------------------
  527.     Menüeinträge anpassen
  528.     ----------------------------------------------------------------------    */
  529. static void check_menu ( void )
  530. {
  531.     menu_icheck(t_menu, M_NUMBERS, imgset==IS_NUMBERS);
  532.     menu_icheck(t_menu, M_LETTERS, imgset==IS_LETTERS);
  533.  
  534.     menu_icheck(t_menu, M_VERY_EASY, level==L_VERY_EASY);
  535.     menu_icheck(t_menu, M_EASY, level==L_EASY);
  536.     menu_icheck(t_menu, M_MEDIUM, level==L_MEDIUM);
  537.     menu_icheck(t_menu, M_DIFF, level==L_DIFFICULT);
  538.     menu_icheck(t_menu, M_VERY_DIFF, level==L_VERY_DIFFICULT);
  539.     
  540. }    /*check_menu*/
  541.  
  542.  
  543.  
  544.  
  545. /*    ----------------------------------------------------------------------
  546.     handle_game() wertet Aktionen im Dialog aus
  547.     ->    msg:    SysGem-Message
  548.         inf:    Dialog-Informationen
  549.     ----------------------------------------------------------------------    */
  550. int handle_game (int msg, WINDOW_INFO *inf)
  551. {
  552.     BOOLEAN        quit_game= FALSE;
  553.     LEVEL        oldlevel= level;
  554.     IMGSET        oldset= imgset;
  555.     int            fy, fx;
  556.     
  557.     /* Umlenken auf andere Messages, damit nicht alles */
  558.     /* programmiert werden muß bzw. extra Routinen     */
  559.     /* angelegt werde müssen. Man ist ja faul ;-)      */
  560.     
  561.     switch (msg)
  562.     {
  563.         case SG_END:    /* Closer auf Menüeintrag "Beenden" umlenken */
  564.             msg= SG_MENU;
  565.             inf->mItem= M_QUIT;
  566.             break;
  567.         case SG_HELP:    /* HELP auf Menüeintrag "Hilfe" umlenken */
  568.             msg= SG_MENU;
  569.             inf->mItem= M_HELP;
  570.             break;
  571.     }
  572.  
  573.  
  574.     switch (msg)
  575.     {
  576.         case SG_NOWIN:    /* Kein Fenster mehr vorhanden -> Abbruch! */
  577.             alert_no_window();
  578.             return(SG_ABORT);
  579.  
  580.         case SG_START:    /* Fenster initialisieren, bevor es gezeichnet wurde */
  581.             LinkImage(inf->id, i_iconify, SUBTITLE);
  582.             init_game(FALSE);
  583.             check_menu();
  584.             break;
  585.  
  586.         case SG_QUIT:    /* Fenster wurde geschlossen */
  587.             return (SG_CONT);
  588.  
  589.         case SG_KEY:    /* Tastendrücke weitergeben */
  590.             return(SG_KEYCONT);
  591.  
  592.         case SG_MENU:    /* Menüeintrag wurde ausgewählt */
  593.             switch (inf->mItem)
  594.             {
  595.                 case M_NEW:            init_game(TRUE);            break;
  596.                 case M_INFO:        open_info();                break;
  597.                 case M_HELP:        CallOnlineHelp("Main");        break;
  598.                 case M_QUIT:        quit_game= TRUE;            break;
  599.                 
  600.                 case M_NUMBERS:        imgset= IS_NUMBERS;            break;
  601.                 case M_LETTERS:        imgset= IS_LETTERS;            break;
  602.                 
  603.                 case M_VERY_EASY:    level= L_VERY_EASY;            break;
  604.                 case M_EASY:        level= L_EASY;                break;
  605.                 case M_MEDIUM:        level= L_MEDIUM;            break;
  606.                 case M_DIFF:        level= L_DIFFICULT;            break;
  607.                 case M_VERY_DIFF:    level= L_VERY_DIFFICULT;    break;
  608.             }
  609.             
  610.             if ( (imgset!=oldset) || (level!=oldlevel) )
  611.             {    check_menu();
  612.             }
  613.  
  614.             break;
  615.         
  616.         case SG_SIZED:    /* Fenster wurde vergrößert */
  617.             break;
  618.         
  619.         case SG_MOVED:    /* Fenster wurde verschoben */
  620.             work.x= inf->clip.x;
  621.             work.y= inf->clip.y;
  622.             break;
  623.  
  624.         case SG_LCLICK1:
  625.         case SG_LCLICK2:    /* Es wurde ins Fenster geklickt */
  626.             /* Koordinaten des angeklickten Feldes berechnen */
  627.             fx= (inf->mx - work.x - BORDER) / imgwidth;
  628.             fy= (inf->my - work.y - BORDER) / imgheight;
  629.  
  630.             /* Wurde das angeklickte Feld verschoben? */
  631.             if (move_field(fy, fx, TRUE))
  632.             {    /* Ja -> Ist das Spiel jetzt gelöst? */
  633.                 if ( game_solved() )
  634.                 {    /* Ja -> Neues Spiel starten? */
  635.                     if ( alert_new_game() )
  636.                     {    /* Ja -> Fenster neu initialisieren */
  637.                         init_game(TRUE);
  638.                     }
  639.                     else
  640.                     {    /* Nein -> Spiel beenden */
  641.                         quit_game= TRUE;
  642.                     }
  643.                 }
  644.             }
  645.             break;
  646.             
  647.         case SG_DRAGDROP:
  648.             alert_no_dragdrop();
  649.             break;
  650.     }
  651.  
  652.  
  653.     if (quit_game)
  654.     {    return (SG_TERM);
  655.     }
  656.  
  657.     return (SG_CONT);
  658.  
  659. } /*handle_game*/
  660.  
  661.  
  662.  
  663.  
  664. /*    ----------------------------------------------------------------------
  665.     open_game() öffnet das Spiel-Fenster
  666.     ----------------------------------------------------------------------    */
  667. static BOOLEAN open_game ( void )
  668. {
  669.     int handle;
  670.     
  671.     if ( (handle=GetHandle(MAINID))>0 )
  672.     {    TopWindow(handle);
  673.         return(TRUE);
  674.     }
  675.     
  676.     handle= OpenWindow(
  677.                 MAINID,                        /* id */
  678.                 "|Little 15",                /* name */
  679.                 "",                            /* info */
  680.                                             /* flags */
  681.                 CLOSER | NAME | MOVER | SMALLER,
  682.                 t_menu,                        /* menu */
  683.                 8,                            /* align */
  684.                 TRUE,                        /* part_redraw */
  685.                 1,                             /* scroll_x */
  686.                 1,                            /* scroll_y */
  687.                 WIDTH*imgwidth+BORDER*2,    /* doc_x */
  688.                 HEIGHT*imgheight+BORDER*2,    /* doc_y */
  689.                 0, 0,                        /* x, y */
  690.                 WIDTH*imgwidth+BORDER*2,    /* w */
  691.                 HEIGHT*imgheight+BORDER*2,    /* h */
  692.                 NULL,                        /* user */
  693.                 redraw_game,                /* redraw */
  694.                 handle_game                    /* action */
  695.             );
  696.  
  697.     if (handle<=0)
  698.     {    alert_no_window();
  699.         return(FALSE);
  700.     }
  701.     
  702.     return(TRUE);
  703.  
  704. } /*open_game*/
  705.  
  706.  
  707.  
  708.  
  709.  
  710. /*    ######################################################################
  711.     #
  712.     # Desktop-Menü
  713.     #
  714.     ######################################################################    */
  715. /*    ----------------------------------------------------------------------
  716.     handle_deskmenu() steuert die Desktop-Menüzeile
  717.     ----------------------------------------------------------------------    */
  718. int handle_deskmenu ( int item )
  719. {
  720.     switch (item)
  721.     {
  722.         case DM_ABOUT:
  723.             open_info();
  724.             break;
  725.         case DM_QUIT:
  726.             return (SG_TERM);
  727.     }
  728.     
  729.     return (SG_CONT);
  730. }    /*handle_deskmenu*/
  731.  
  732.  
  733.  
  734. /*    ----------------------------------------------------------------------
  735.     handle_acc_open()
  736.     ----------------------------------------------------------------------    */
  737. void handle_acc_open ( void )
  738. {
  739.     open_game();
  740. }    /*handle_acc_open*/
  741.  
  742.  
  743.  
  744. /*    ----------------------------------------------------------------------
  745.     handle_acc_close()
  746.     ----------------------------------------------------------------------    */
  747. void handle_acc_close ( void )
  748. {
  749. }    /*handle_acc_close*/
  750.  
  751.  
  752.  
  753.  
  754. /*    ----------------------------------------------------------------------
  755.     handle_unknown()
  756.     ----------------------------------------------------------------------    */
  757. void handle_unknown ( int *msg )
  758. {
  759.     switch (*msg)
  760.     {
  761.         case 0x4711:    /* VA-Start */
  762.             open_game();
  763.             break;
  764.     }
  765.     
  766. }    /*handle_unknown*/
  767.  
  768.  
  769.  
  770.  
  771.  
  772. /*    ######################################################################
  773.     #
  774.     # Hauptroutine und Initialisierung
  775.     #
  776.     ######################################################################    */
  777. /*    ----------------------------------------------------------------------
  778.     Zufallsgenerator mit Hilfe der Uhrzeit initialisieren
  779.     ----------------------------------------------------------------------    */
  780. static void init_rand ( void )
  781. {
  782.     time_t    zeit;
  783.     struct    tm *clock;
  784.     
  785.     time(&zeit);
  786.     clock = localtime(&zeit);
  787.     srand( (clock->tm_hour)*100 + (clock->tm_min)*10 + (clock->tm_sec) );
  788.  
  789. }    /* init_rand */
  790.  
  791.  
  792.  
  793. /*    ----------------------------------------------------------------------
  794.     Grafikdaten initialisieren
  795.     ----------------------------------------------------------------------    */
  796. static void init_graphics ( void )
  797. {
  798.     imgwidth=    t_imag[NUMB_00].ob_spec.bitblk->bi_wb*8;
  799.     imgheight=    t_imag[NUMB_00].ob_spec.bitblk->bi_hl;
  800.     
  801.     /* MFDB's initialisieren */
  802.     memset( &mfdb_field, 0, sizeof(MFDB));
  803.     mfdb_field.fd_w= imgwidth;
  804.     mfdb_field.fd_h= imgheight;
  805.     mfdb_field.fd_wdwidth= imgwidth/16;
  806.     mfdb_field.fd_stand=  0;
  807.     mfdb_field.fd_nplanes= 1;
  808.  
  809.     memset( &mfdb_screen, 0, sizeof(MFDB));
  810.  
  811.     /* Farbindizes für vrt_cpyfm() */
  812.     color[0]= 1;
  813.     color[1]= 0;
  814.  
  815.     /* Quell-koordinaten für vrt_cpyfm() */
  816.     pxy[0]= 0;
  817.     pxy[1]= 0;
  818.     pxy[2]= imgwidth-1;
  819.     pxy[3]= imgheight-1;
  820.     
  821.  
  822. }    /*init_graphics*/
  823.  
  824.  
  825. /*    ----------------------------------------------------------------------
  826.     Applikation initialisieren
  827.     ----------------------------------------------------------------------    */
  828. static void init_app ( void )
  829. {
  830. #if (!RSC_INCLUDE)
  831.     /* Objektadressen ermitteln */
  832.     t_deskmenu=        RscAdr(R_TREE, T_DESKMENU);
  833.     t_menu=            RscAdr(R_TREE, T_MENU);
  834.     t_info=            RscAdr(R_TREE, T_INFO);
  835.     t_fair=            RscAdr(R_TREE, T_FAIR);
  836.     t_auth=            RscAdr(R_TREE, T_AUTH);
  837.     t_imag=            RscAdr(R_TREE, T_IMAG);
  838.     a_new_game=        (char *) RscAdr(R_STRING, A_NEW_GAME);
  839.     a_no_window=    (char *) RscAdr(R_STRING, A_NO_WINDOW);
  840.     a_no_dragdrop=    (char *) RscAdr(R_STRING, A_NO_DRAGDROP);
  841.     a_quit=            (char *) RscAdr(R_STRING, A_QUIT);
  842. #endif
  843.  
  844.     /* Menüzeilen anmelden */
  845.     UseWindowMenu();
  846.     InitMenuLine(t_deskmenu);
  847.     InitMenuLine(t_menu);
  848.     
  849.     /* Dialoge anmelden, den Rückgabewert ignorieren wird einfach. */
  850.     NewDialog(t_info);    
  851.     NewDialog(t_fair);
  852.     NewDialog(t_auth);
  853.  
  854.  
  855.     /* Default-Koordinaten der Fenster setzen. */
  856.     /* Bei [-1|-1] wird zentriert.             */
  857.     x_main= -1;    y_main= -1;
  858.     x_info= -1;    y_info= -1;
  859.     
  860.     /* Bitblocks der G_IMAGEs zum Ikonifizieren ermitteln */
  861.     i_iconify= t_imag[IMG_ICONIFY].ob_spec.bitblk;
  862.     dh_iconify= t_imag[IMG_DH].ob_spec.bitblk;
  863.  
  864.     /* Imageblock für iconifiziertes anmelden */
  865.     LinkMainImage(i_iconify, SUBTITLE);
  866.  
  867.     /* Onlinehilfe setzen */
  868.     SetOnlineHelp("ST-GUIDE", "", HYPFILE);
  869.  
  870.     ShortCutColor(BLACK);            /* Schwarze Unterstriche  benutzen*/
  871.     SetAlertTitle("");                /* Normale Alert-Boxen-Überschrift */
  872.  
  873.     /* Spiel-Defaults setzen */
  874.     imgset= IS_NUMBERS;
  875.     level= L_MEDIUM;
  876.         
  877. }    /*init_app*/
  878.  
  879.  
  880.  
  881.  
  882. /*    ----------------------------------------------------------------------
  883.     main()
  884.     <-    !=0:    ein Fehler ist aufgetreten
  885.     ----------------------------------------------------------------------    */
  886.  
  887. /* Hier die Schlüssel für SysGem2 angeben */
  888.  
  889. #define    MY_KEY1            0x0L
  890. #define    MY_KEY2            0x0L
  891.  
  892.  
  893. int main ( void )
  894. {
  895. #if RSC_INCLUDE
  896.     int i;        
  897. #endif
  898.     BOOLEAN rsc_loaded;
  899.  
  900.     if (InitGem(ACC_NAME, APP_ID, APP_NAME))
  901.     {
  902.         SetKey(MY_KEY1, MY_KEY2);
  903.         GetParStruct(&par);
  904.         
  905. #if RSC_INCLUDE
  906.         /* eingebundene Resource initialisieren */
  907.         for (i=0; i<NUM_OBS; i++)
  908.         {    rsrc_obfix (&rs_object[i], 0);
  909.         }
  910.         rsc_loaded= TRUE;
  911. #else
  912.         ShowBee();
  913.         if ( LoadResource(RSC_NAME, FALSE)>=0 )
  914.         {    rsc_loaded= TRUE;
  915.             ShowArrow();
  916.         }
  917.         else
  918.         {    rsc_loaded= TRUE;
  919.             ShowArrow();
  920.             if (!accessory)
  921.             {    alert_rsc_error();
  922.             }
  923.         }
  924. #endif
  925.  
  926.         if ( rsc_loaded )
  927.         {    /* Unter MultiTOS Menüeintrag setzen, wenn Programm */
  928.             if ( (!accessory) && (par.aes_version>=0x0400) )
  929.             {    menu_register(par.appl_id, ACC_NAME);
  930.             }
  931.  
  932.             init_app();
  933.             init_graphics();
  934.             init_rand();
  935.             
  936.             if (accessory)
  937.             {    SetAccProc(handle_acc_open, handle_acc_close);
  938.                 HandleSysGem();
  939.             }
  940.             else
  941.             {    if (!par.multitask)
  942.                 {    SetDeskTopMenu(t_deskmenu, handle_deskmenu);
  943.                 }
  944.                 if (open_game())
  945.                 {    HandleSysGem();
  946.                 }
  947.             }
  948.         }
  949.         else
  950.         {    if (accessory)
  951.             {    while (TRUE) evnt_timer(10000,0);
  952.             }
  953.         }
  954.         ExitGem();
  955.     }
  956.     
  957.     return (0);
  958.     
  959. }    /*main*/
  960.  
  961.  
  962. /*    ######################################################################
  963.     # little15.c
  964.     ######################################################################    */
  965.